package com.fast.log;

import ch.qos.logback.classic.spi.CallerData;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.classic.spi.LoggingEvent;
import ch.qos.logback.classic.spi.ThrowableProxy;
import com.alibaba.fastjson.JSONObject;
import org.slf4j.MDC;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Objects;

public class TraceLoggerHandler {

    private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");

    private static String ENV = System.getenv("DEPLOY_ENV");

    private static String SERVICE = System.getenv("DEPLOY_APP");

    private static String POD_NAME = System.getenv("HOSTNAME");

    private static String VERSION = System.getenv("DEPLOY_VERSION");



    public static String getMessage(LoggingEvent e) {
        String message = e.getFormattedMessage();
        JSONObject tracerLogger = getTracerLogger(message);

        //原始日志属性
        putValue(tracerLogger, "message", message);
        if (Objects.nonNull(e.getThrowableProxy())) {
            ThrowableProxy throwableProxy = (ThrowableProxy) e.getThrowableProxy();
            putValue(tracerLogger, "errorMsg",  getStackTrace(throwableProxy.getThrowable()));
            putValue(tracerLogger, "errorClassName", throwableProxy.getClassName());
        }
        putValue(tracerLogger, "level", e.getLevel().levelStr);
        putValue(tracerLogger, "loggerName", e.getLoggerName());
        putValue(tracerLogger, "loggerMethod", getMethod(e));

        //链路属性
        String traceId = MDC.get("traceId");
        String spanId = MDC.get("spanId");
        //设置链路id
        putValue(tracerLogger, "traceId", traceId);
        putValue(tracerLogger, "spanId", spanId);

        //服务属性
        putValue(tracerLogger, "env", ENV);
        putValue(tracerLogger, "service", SERVICE);
        putValue(tracerLogger, "podName", POD_NAME);
        putValue(tracerLogger, "version", VERSION);

        //当前日志的时间戳
        putValue(tracerLogger, "timestamp", getTime());
        return tracerLogger.toJSONString();
    }
    public static String getStackTrace(Throwable throwable) {
        StringWriter sw = new StringWriter();
        PrintWriter pw = new PrintWriter(sw, true);
        throwable.printStackTrace(pw);
        return sw.getBuffer().toString();
    }

    private static void putValue(JSONObject tracerLogger, String key, String value) {
        if (Objects.isNull(value)) {
            return;
        }
        tracerLogger.put(key, value);
    }

    private static JSONObject getTracerLogger(String message) {
        try {
            return JSONObject.parseObject(message);
        } catch (Exception e) {
            return new JSONObject();
        }
    }

    private static String getMethod(ILoggingEvent le) {
        StackTraceElement[] cda = le.getCallerData();
        if (cda != null && cda.length > 0) {
            return cda[0].getMethodName();
        } else {
            return CallerData.NA;
        }
    }

    private static String getTime() {
        return LocalDateTime.now().format(DATE_FORMATTER);
    }

    public static void main(String[] args) {
        System.out.println(getTime());
    }
}
